// 获取url参数
export function getQueryParams(url: string): Record<string, unknown> {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf('?') + 1);
  const obj: Record<string, unknown> = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

// 复制到粘贴板
export function copyToClipboard(text: string): boolean {
  const textarea = document.createElement('textarea');
  textarea.readOnly = true; // 防止iOS下自动唤起键盘
  textarea.style.position = 'absolute';
  textarea.style.left = '-999px';
  textarea.value = text;
  document.body.appendChild(textarea);
  textarea.select();
  let result = true;
  try {
    document.execCommand('copy');
    result = true;
  } catch (err) {
    result = false;
  } finally {
    document.body.removeChild(textarea);
  }
  return result;
}

// 异步加载 script 脚本
export function loadScript(url: string, id: string, noCache?: boolean): Promise<void> {
  return new Promise((resolve, reject) => {
    // 检查是否已存在相同ID或URL的script标签
    if (id && document.getElementById(id)) {
      resolve();
      return;
    }
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.onload = () => {
      cleanup(script);
      resolve();
    };
    script.onerror = (err) => {
      cleanup(script);
      reject(new Error(`Failed to load script: ${url}`));
    };
    script.src = url;
    if (noCache) {
      script.src += (url.indexOf('?') >= 0 ? '&' : '?') + 't=' + Date.now();
    }
    if (id) script.id = id;
    // 添加到文档头部开始加载
    document.head.appendChild(script);
    // 清理事件监听器防止内存泄漏
    function cleanup(node: any) {
      node.onload = node.onerror = null;
    }
  });
}

export interface ImageSize {
  width: number;
  height: number;
}

// 获取图片原始宽高
export function getImageSize(src: string): Promise<ImageSize> {
  return new Promise((resolve) => {
    const img = document.createElement('img');
    img.src = src;
    img.style.opacity = '0';
    document.body.appendChild(img);

    img.onload = () => {
      const imgWidth = img.clientWidth;
      const imgHeight = img.clientHeight;
      img.onload = null;
      img.onerror = null;
      document.body.removeChild(img);
      resolve({ width: imgWidth, height: imgHeight });
    };
    img.onerror = () => {
      img.onload = null;
      img.onerror = null;
    };
  });
}

// 文件生成DataURL(图片预览地址)
export function getFileDataURL(file: File): Promise<string> {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.addEventListener('load', () => {
      resolve(reader.result as string);
    });
    reader.readAsDataURL(file);
  });
}

// 判断系统是否包含某字体
export function isFontInstalled(fontFamily: string): boolean {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
  const baselineFont = '72px Arial'; // 基准字体
  if (!context) return false;
  context.font = baselineFont;
  const baselineWidth = context.measureText(text).width;
  const testFont = `72px ${fontFamily}, Arial`;
  context.font = testFont;
  const testWidth = context.measureText(text).width;
  return testWidth !== baselineWidth; // 若宽度与基准不同则字体存在
}

// 获取和设置存储 localStorage
export function getStorage<T>(key: string, initValue?: any): T {
  let initial = initValue;
  try {
    const jsonString = localStorage.getItem(key);
    if (jsonString) {
      initial = JSON.parse(jsonString);
    }
  } catch (e) {}
  return initial;
}

export function setStorage<T>(key: string, value: T): void {
  localStorage.setItem(key, JSON.stringify(value));
}

// 获取和设置存储 sessionStorage
export function getSession<T>(key: string, initValue?: any): T {
  let initial = initValue;
  try {
    const jsonString = sessionStorage.getItem(key);
    if (jsonString) {
      initial = JSON.parse(jsonString);
    }
  } catch (e) {}
  return initial;
}

export function setSession<T>(key: string, value: T): void {
  sessionStorage.setItem(key, JSON.stringify(value));
}
